#include "Generator.h"

void Generator::map_root_path(Node* node, vector<Direction> *path) {
    Node* actual = node;
    while(actual->get_father() != NULL) {
        path->push_back(actual->get_father()->get_left() == actual ? LEFT : RIGHT);
        actual = actual->get_father();
    }
}

void Generator::generate_tree(Node* root, Node* paramActual, Node* leaf, vector<Node* >* tree_list, Orientation orientation) {
    Node* copy = new Node(root);
    vector<Direction> path;
    map_root_path(paramActual, &path);
    Node* actual = copy;
    while(!path.empty()) {
        actual = path.back() == LEFT ? actual->get_left() : actual->get_right();
        path.pop_back();
    }
    Node* father = actual->get_father();
    Node* newNode = new Node(actual, orientation, new Node(leaf));
    if(father) {
        if(father->get_left() == actual)
            father->set_left(newNode);
        else
            father->set_right(newNode);
        tree_list->push_back(copy);
    } else {
        tree_list->push_back(newNode);
    }
}

void Generator::generate_trees(Node* root, Node* paramActual, Node* leaf, vector<Node* >* tree_list) {
    if(root) {
        generate_tree(root, paramActual, leaf, tree_list, HORIZONTAL);
        generate_tree(root, paramActual, leaf, tree_list, VERTICAL);
        if(!paramActual->is_leaf()) {
            this->generate_trees(root, paramActual->get_left(), leaf, tree_list);
            this->generate_trees(root, paramActual->get_right(), leaf, tree_list);
        }
    } else {
        tree_list->push_back(new Node(leaf));
    }
}

void Generator::generate_trees(vector<Node*> nodes, vector<Node*>* trees) {
    for(vector<Node*>::iterator it_node = nodes.begin(); it_node != nodes.end(); it_node++) {
        if(trees->empty()) {
            trees->push_back(new Node(*it_node));
        } else {
            vector<Node*> local_trees(trees->begin(), trees->end());
            trees->clear();
            for(vector<Node*>::iterator it_tree = local_trees.begin(); it_tree != local_trees.end(); it_tree++) {
                generate_trees(*it_tree, *it_tree, new Node(*it_node), trees);
            }            
        }
    }
}

/*void Generator::generate_trees(vector<Node*>* roots, Node* leaf, vector<Node* >* trees) {
    for(vector<Node*>::iterator it = roots->begin(); it != roots->end(); it++)
        generate_trees(*it, *it, leaf, trees);
}*/
